
template<class T>
void Array<T>::valid() const{
    ASSERT(this != 0, "internal error");
}

template<class T>
Array<T>::Array()
//:   _size(0), size(_size)
{
}

/*
template<class T>
Array<T>::Array(const Array& arr)
:   _size(0), size(_size){
}
*/

template<class T>
void Array<T>::valid(const int i) const{
    ASSERT(i >= 0 && i < this->size(), "invalid index");
}

template<class T>
void Array<T>::valid(const int i, const int count) const{
    if (count > 0){
        valid(i);
        valid(i + count - 1);
    }
}

template<class T>
const T& Array<T>::operator[](const int i) const{
    this->valid(i);
    return this->start()[i];
}

template<class T>
T& Array<T>::operator[](const int i){
    this->valid(i);
    return this->start()[i];
}

template<class T>
void Array<T>::move(const int start, const T source[], const int count){
    valid(start, count);
    T* _raw = this->start();

    if ((source >= &_raw[0] && source <= &_raw[this->size()-1]) ||
        (source + count - 1 >= &_raw[0] && source + count -1 <= &_raw[this->size()-1])){

        if (&_raw[start] < source){
            for (int i = 0; i < count; i++){
//              const T t = source[i];
                _raw[start + i] = source[i];
            } 
        }else{
            for (int i = count - 1; i >= 0; i--){
//              const T t = source[i];
                _raw[start + i] = source[i];
            } 
        }
    }else{
        for (int i = 0; i < count; i++){
//          const T t = source[i];
            _raw[start + i] = source[i];
        } 
    }
}

template<class T>
void Array<T>::move(const int start, const Array<T>& src, const int srcStart, const int count){
    src.valid(srcStart, count);
    
    this->move(start, &src[0]+srcStart, count);
}


template<class T>
void Array<T>::assign(const Array<T>& src){
    if (src.size() != this->size()){
        this->resize(src.size());
        ASSERT(src.size() == this->size(), "invalid size")
    }
    this->move(0, src, 0, this->size());
}

template<class T>
void Array<T>::operator=(const Array<T>& src){
    this->assign(src);
}

template<class T>
void Array<T>::fill(const int start, const T& o, const int count){
    this->valid(start, count);
    for (int i = 0; i < count; i++){
        this->start()[start + i] = o;
    } 
}


template<class T>
void Array<T>::zeroize(){
    const T o = T();
    this->fill(0, o, this->size());
}


